package com.seven.webhook.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.extra.ssh.ChannelType;
import cn.hutool.extra.ssh.JschUtil;
import cn.hutool.extra.ssh.Sftp;
import cn.hutool.json.JSONUtil;
import com.gs.cd.cloud.common.ApiResult;
import com.jcraft.jsch.*;
import com.seven.webhook.component.prometheus.PrometheusApiUtils;
import com.seven.webhook.model.bean.yaml.PrometheusYaml;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.yaml.snakeyaml.Yaml;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;

@RestController
@RequestMapping("webhook/matcher")
@Log4j2
public class MatcherController {
    @Value("${prometheus.yml.filePath}")
    private String prometheusYmlPath;
    @Value("${prometheus.node.dir}")
    private String prometheusNodeDir;

    public String getPrometheusYmlPath() {
        return prometheusYmlPath;
    }

    @Data
    private static class MatcherInfo {
        private String ip;
        private String username;
        private String password;
        private Integer port = 22;
    }

    @PostMapping("add/node_exporter")
    public ApiResult addNodeExporter(@RequestBody MatcherInfo matcherInfo) throws IOException {
        //建立ssh连接
        JSch jSch = new JSch();
        //设置JSch 的日志，可以看到具体日志信息
        JSch.setLogger(new Logger() {
            @Override
            public boolean isEnabled(int level) {
                return true;
            }

            @Override
            public void log(int level, String message) {
                System.out.println("logger:" + message);
            }
        });
        try {
            Session session = jSch.getSession(matcherInfo.getUsername(), matcherInfo.getIp());
            session.setPassword(matcherInfo.getPassword());
            //忽略第一次连接时候 hostkey 检查
            session.setConfig("StrictHostKeyChecking", "no");
            //设置首选的身份验证方式
            session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
            synchronized (MatcherController.class) {
                session.connect(10000);
            }
            if (session.isConnected()) {
                log.info("连接成功");
                ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp");
                sftp.connect(10000);
                log.info("home" + sftp.getHome());
                sftp.put(prometheusNodeDir + "/node_exporter-0.18.1.linux-amd64.tar.gz", sftp.getHome());
                sftp.put(prometheusNodeDir + "/init-node-exporter.sh", sftp.getHome());
                log.info("上传成功");
                ChannelExec exec = (ChannelExec) session.openChannel("exec");
                exec.setCommand("sh init-node-exporter.sh");
                exec.connect(10000);
                log.info("执行成功");
            }
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
            return ApiResult.error("错误：" + e);
        }
        /*Session session = JschUtil.getSession(matcherInfo.getIp(), matcherInfo.getPort(), matcherInfo.getUsername(), matcherInfo.getPassword());
        // 设置keep-alive消息发送间隔（milliseconds）
        session.setServerAliveCountMax(1);
        // 设置发送keep-alive消息的最大次数
        try {
            session.setServerAliveInterval(0);
            //第一次登陆时候，是否需要提示信息
            session.setConfig("StrictHostKeyChecking", "no");
            //设置ssh的DH秘钥交换
            session.setConfig("kex", "diffie-hellman-group1-sha1");
            //跳过Kerberos username 身份验证提示
            session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
            // 通过Session建立链接
            synchronized (MatcherController.class) {
                session.connect();
            }
        } catch (JSchException e) {
            e.printStackTrace();
        }
        if (session.isConnected()) {
            log.info("连接成功");
        } else {
            return ApiResult.error("连接失败");
        }
        try {
            Sftp sftp = JschUtil.createSftp(session);
            // TODO: 13/11/2020 遍历获取文件
            sftp.put(prometheusNodeDir + "/node_exporter-0.18.1.linux-amd64.tar.gz", sftp.home());
            sftp.put(prometheusNodeDir + "/init-node-exporter.sh", sftp.home());
//            sftp.put(FileUtil.getInputStream("node_exporter-0.18.1.linux-amd64.tar.gz"), "node_exporter-0.18.1.linux-amd64.tar.gz");
//            sftp.put(FileUtil.getInputStream("init-node-exporter.sh"), "init-node-exporter.sh");
        } catch (Exception e) {
            return ApiResult.error("无法连接sftp" + e);
        }
        //解压并执行 nohup ./node_exporter & 命令
        try {
            String s = JschUtil.exec(session, "sh init-node-exporter.sh", StandardCharsets.UTF_8);
            log.info("执行结果:" + s);
        } catch (Exception e) {
            return ApiResult.error("执行sh错误" + e.getMessage());
        } finally {
            JschUtil.closeAll();
        }*/
        //修改配置
        if (prometheusYmlPath == null) {
            throw new RuntimeException("prometheusYmlPath is null");
        }
        Yaml yaml = new Yaml();
        BufferedReader reader = FileUtil.getReader(prometheusYmlPath, "UTF-8");
        PrometheusYaml prometheusYaml = yaml.loadAs(reader, PrometheusYaml.class);
        reader.close();
        prometheusYaml.getScrape_configs().forEach(scrapeConfigs -> {
            if ("node exporter".equals(scrapeConfigs.getJob_name())) {
                scrapeConfigs.getStatic_configs().forEach(staticConfigs -> {
                    List<String> targets = staticConfigs.getTargets();
                    targets.add(matcherInfo.getIp() + ":9100");
                });
            }
        });
        System.out.println(JSONUtil.toJsonStr(prometheusYaml));
        BufferedWriter writer = FileUtil.getWriter(prometheusYmlPath, "UTF-8", false);
        yaml.dump(prometheusYaml, writer);
        writer.close();
        //激活prometheus
        PrometheusApiUtils.activeRule();
        return ApiResult.success();
    }

}
